package smb.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class AuthenticationInterceptor implements HandlerInterceptor {
    private static final String CAS_NAME = "http://localhost:8080";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request.getMethod().equalsIgnoreCase("OPTIONS"))
            return true;
        String tokenInParameter = request.getParameter("token");
        if (tokenInParameter == null) {
            // 请求参数中没有token
            String tokenInHeader = request.getHeader("Authorization");
            if (tokenInHeader == null) {
                // 头部没有token
                String tokenInSession = (String) request.getSession().getAttribute("token");
                if (tokenInSession == null) {
                    // session中也没有token
                    redirectToLogin(request, response);
                    return false;
                } else {
                    // session中有token
                    return authenticateToken(request, response, tokenInSession);
                }
            } else {
                // 头部有token
                return authenticateToken(request, response, tokenInHeader);
            }
        } else {
            // 请求参数中有token
            return authenticateToken(request, response, tokenInParameter);
        }
    }

    // 重定向到CAS登录页面
    private static void redirectToLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        StringBuffer url = request.getRequestURL();
        String returnAddress = URLEncoder.encode(url.toString(), "UTF-8");
//        response.sendRedirect(CAS_NAME + "/login-page?return-address=" + returnAddress);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }

    // 请求CAS验证token，获取用户信息
    private static boolean authenticateToken(HttpServletRequest request, HttpServletResponse response, String token) throws IOException {
        User user;
        try {
            // 请求CAS进行验证
            user = requestCAS(token);
        } catch (IOException e) {
            // 请求CAS验证失败
            redirectToLogin(request, response);
            return false;
        }
        if (user == null) {
            // token无效
            redirectToLogin(request, response);
            return false;
        } else {
            // token有效
            // 创建session，放入user和token
            request.getSession().setAttribute("user", user);
            request.getSession().setAttribute("token", token);
            return true;
        }
    }

    // 向CAS发送请求
    private static User requestCAS(String token) throws IOException {
        URL url = new URL(CAS_NAME + "/user-info-api");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Accept", "application/json");
        conn.setRequestProperty("Accept-Charset", "UTF-8");
        conn.setRequestProperty("Authorization", token);
        ObjectMapper objectMapper = new ObjectMapper();
        User user = objectMapper.readValue(conn.getInputStream(), User.class);
        conn.disconnect();
        return user;
    }
}
